home *** CD-ROM | disk | FTP | other *** search
/ Resource for Source: C/C++ / Resource for Source - C-C++.iso / misc_src / dpmifi / fixdpmi.c next >
C/C++ Source or Header  |  1995-11-01  |  5KB  |  196 lines

  1. /* FIXDPMI.C - Fixes Borland C++ 3.0 DPMILOAD.EXE
  2.  * to work properly under DESQVIEW
  3.  *
  4.  * DPMILOAD mishandled setting it's own termination address
  5.  * by setting only the OFFSET at PSP:000Ah instead of the
  6.  * entire FAR POINTER.  Since DV intercepts all terminations,
  7.  * and DPMILOAD had already terminated once as a TSR, the
  8.  * SEGMENT of the termination address was pointing into DV
  9.  * code, so when the OFFSET only was changed before the second
  10.  * exit, the 4C00, INT 21 call exited to nonsense.
  11.  
  12.  * This patch rearranges the portion of code which blew it
  13.  * and unloads the TSR DPMILOAD from memory correctly.
  14.  
  15.  * This patch fixes DPMILOAD so you can load any DPMI BC++ 3.0 TOOL
  16.  * in a window under DV.  The only unusual setting I use is Keyboard
  17.  * conflict 8.  The IDE still likes to steal some of the <ALT> key 
  18.  * presses.
  19.  
  20.  * To spare you debug manipulations, I wrote this short program
  21.  * If you don't have a 'C' compiler, use the binary I've provided
  22.  *
  23.  * If you have any questions, or problems, feel free to contact me.
  24.  *
  25.  * Philip B. Gardner 70053,3157
  26.  */
  27.  
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <process.h>
  31.  
  32. char help[] = "fixdpmi (dpmiload.exe's pathname) [-u]\n"
  33.               "   -u is optional and reverses the patch" ;
  34. #define datalen     88
  35.  
  36. unsigned char patch[3][datalen] = {
  37.     {
  38.     0x5E,0x07,0x1F,0xEB,0x88,0x8C,0xD0,0x8B,
  39.     0xDC,0x8B,0xEC,0x8B,0x4E,0x04,0x8B,0x26,
  40.     0x0F,0x00,0x8E,0x16,0x07,0x00,0x51,0x83,
  41.     0xEB,0x0E,0x53,0x50,0xE8,0x82,0x00,0xE8,
  42.     0xA6,0xD1,0xE8,0x19,0xFC,0xE8,0x67,0x00,
  43.     0xE8,0x52,0x00,0xE8,0x9A,0x00,0xE8,0xBB,
  44.     0x00,0x58,0x5B,0x59,0x8B,0x16,0x0B,0x00,
  45.     0x8E,0xC2,0x8B,0x16,0x6C,0x00,0x26,0x89,
  46.     0x16,0x10,0x00,0x26,0x89,0x0E,0x0A,0x00,
  47.     0x8E,0xC2,0x26,0x89,0x1E,0x2E,0x00,0x26,
  48.     0xA3,0x30,0x00,0xB8,0x00,0x4C,0xCD,0x21
  49.     },
  50.     {
  51.     0x5E,0x07,0x1F,0xEB,0x88,0x8C,0xD0,0x89,
  52.     0xE5,0xC4,0x4E,0x04,0x8B,0x26,0x0F,0x00,
  53.     0x8E,0x16,0x07,0x00,0x50,0x83,0xED,0x0E,
  54.     0x55,0x51,0x06,0x90,0xE8,0x82,0x00,0xE8,
  55.     0xA6,0xD1,0xE8,0x19,0xFC,0xE8,0x67,0x00,
  56.     0xE8,0x52,0x00,0xE8,0x9A,0x00,0xE8,0xBB,
  57.     0x00,0x8B,0x16,0x6C,0x00,0x8E,0x1E,0x0B,
  58.     0x00,0x89,0x16,0x10,0x00,0x8F,0x06,0x0C,
  59.     0x00,0x8F,0x06,0x0A,0x00,0x8E,0xDA,0x8F,
  60.     0x06,0x2E,0x00,0x8F,0x06,0x30,0x00,0xEB,
  61.     0x00,0xEB,0x00,0xB8,0x00,0x4C,0xCD,0x21
  62.     }
  63.     } ;
  64.  
  65. #define start     (0x3A68L)
  66. #define broke     (patch[0])
  67. #define fixit     (patch[1])
  68. #define buffer     (patch[2])
  69.  
  70. void main(int argc, char *argv[])
  71. {
  72.     FILE *fp ;
  73.     int state ;
  74.     char *search = broke ;
  75.     char *update = fixit ;
  76.  
  77.     for(state = 4 ; state ; state--)
  78.     
  79.     switch(state)    {
  80.  
  81.         case 4:
  82.             if (argc < 2)    {
  83.                 puts(help) ;
  84.                 goto out ;
  85.                 }
  86.             break ;
  87.         case 3:
  88.             if ((fp = fopen(argv[1],"rb+")) == NULL)    {
  89.                 printf("Unable able to open %s\n",argv[1]) ;
  90.                 goto out ;
  91.                 }
  92.             if (argc > 2 && argv[2][0] == '-')    {
  93.                 switch(argv[2][1])    {
  94.                     case 'u':
  95.                     case 'U':
  96.                         update = broke ;
  97.                         search = fixit ;
  98.                     }
  99.                 }
  100.             break ;
  101.         case 2:
  102.             if (fseek(fp,start,SEEK_SET)
  103.                 || fread(buffer,1,datalen,fp) != datalen
  104.                 || memcmp(buffer,search,datalen))    {
  105.                 printf("Wrong version of %s\n",argv[1]) ;
  106.                 goto out ;
  107.                 }
  108.             break ;
  109.         case 1:
  110.             if (fseek(fp,-datalen,SEEK_CUR)
  111.                 || fwrite(update,1,datalen,fp) != datalen)    {
  112.                 printf("Error patching %s\n",argv[1]) ;
  113.                 goto out ;
  114.                 }
  115.             break ;
  116.         case 0:
  117.             printf("Successfully patched %s\n",argv[1]) ;
  118.         }
  119.  
  120. out:
  121.     if (fp != NULL)    fclose(fp) ;
  122.     exit(state) ;
  123.     }
  124.  
  125. /*    ---------- BUG ---------- 
  126.  
  127.     MOV     AX,SS            ; segment=int 2Fh vector,offset=386d
  128.     MOV     BX,SP
  129.     MOV     BP,SP
  130.     MOV     CX,[BP+04]        ; CX = offset of new termination address
  131.     MOV     SP,[000F]
  132.     MOV     SS,[0007]
  133.     PUSH    CX
  134.     SUB     BX,+0E            ; simulate register storage space of DOS exec 
  135.     PUSH    BX
  136.     PUSH    AX
  137.     CALL    3909            ; undo INT 2Fh
  138.     CALL    0A30            ; returns by way of switching to protected mode
  139.     CALL    34A6
  140.     CALL    38F7
  141.     CALL    38E5
  142.     CALL    3930
  143.     CALL    3954
  144.     POP     AX
  145.     POP     BX
  146.     POP     CX
  147.     MOV     DX,[000B]        ; still in protected mode
  148.     MOV     ES,DX
  149.     MOV     DX,[006C]
  150.     ES:
  151.     MOV     [0010],DX
  152.     ES:
  153.     MOV     [000A],CX        ; dpmiload's PSP termination address offset
  154.     MOV     ES,DX
  155.     ES:
  156.     MOV     [002E],BX        ; client's last dos stack
  157.     ES:
  158.     MOV     [0030],AX
  159.     MOV     AX,4C00
  160.     INT     21
  161. */
  162.  
  163. /*    ---------- FIX ---------- 
  164.  
  165.     MOV     AX,SS            ; segment=int 2Fh vector,offset=386d
  166.     MOV     BP,SP
  167.     LES     CX,[BP+04]        ; ES not needed now I'm pretty sure
  168.     MOV     SP,[000F]
  169.     MOV     SS,[0007]
  170.     PUSH    AX
  171.     SUB     BP,+0E            ; simulate register storage space of DOS exec 
  172.     PUSH    BP
  173.     PUSH    CX                ; push full terminate address (ES:CX)
  174.     PUSH    ES
  175.     NOP
  176.     CALL    3909            ; undo INT 2Fh
  177.     CALL    0A30            ; returns by way of switching to protected mode
  178.     CALL    34A6
  179.     CALL    38F7
  180.     CALL    38E5
  181.     CALL    3930
  182.     CALL    3954
  183.     MOV     DX,[006C]        ; still in protected mode
  184.     MOV     DS,[000B]
  185.     MOV     [0010],DX
  186.     POP     [000C]            ; FIX!! dpmiload's PSP termination address segment
  187.     POP     [000A]            ; dpmiload's PSP termination address offset
  188.     MOV     DS,DX
  189.     POP     [002E]            ; client's last dos stack
  190.     POP     [0030]
  191.     JMP     38B9
  192.     JMP     38BB
  193.     MOV     AX,4C00            ; exit
  194.     INT     21
  195. */
  196.